/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.generator.item;

import java.util.ArrayList;

import io.iec.edp.caf.generator.baseInfo.AnnotationInfo;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import io.iec.edp.caf.generator.BaseGenerator;
import io.iec.edp.caf.generator.BaseGeneratorContext;
import io.iec.edp.caf.generator.baseInfo.CompilationUnitInfo;
import io.iec.edp.caf.generator.baseInfo.TypeGeneratorInfo;
import io.iec.edp.caf.generator.baseInfo.TypeInfo;

/**
 * @author liu_wei
 */
public abstract class ItemInfoGenerator extends BaseGenerator {

    //字段
    protected CompilationUnitInfo compileUnit;

    protected ItemGeneratorContext getContext() {
        return (ItemGeneratorContext) super.getContext();
    }

    //构造函数
    protected ItemInfoGenerator(CompilationUnitInfo compileUnit) {
        this.compileUnit = compileUnit;
    }

    //初始化
    @Override
    protected final BaseGeneratorContext createContext() {
        ItemGeneratorContext context = createItemInfoContext();
        TypeGeneratorInfo info = createItemInfo();
        info.setAst(ast);
        context.setItemInfo(info);
        return context;
    }

    protected abstract ItemGeneratorContext createItemInfoContext();

    protected abstract TypeGeneratorInfo createItemInfo();

    @Override
    protected void beforeGenerate() {
        addAllParentInterface();
        setItemBasicInfo();
    }

    @Override
    protected ArrayList<BaseGenerator> createChildGenerators() {
        ArrayList<BaseGenerator> list = super.createChildGenerators();
        if (list == null) {
            list = new ArrayList<BaseGenerator>();
        }
        return list;
    }

    private void addAllParentInterface() {
        addParentInterface();
    }

    private void addParentInterface() {
        ArrayList<TypeInfo> parentInterfaceList = addParentInterfaces();
        if (parentInterfaceList == null || parentInterfaceList.size() < 1) {
            return;
        }
        // C# TO JAVA CONVERTER TODO TASK: There is no equivalent to implicit typing in
        // Java:
        for (TypeInfo parentInterface : parentInterfaceList) {
            String typeFullName = parentInterface.getTypeFullName();
            if (typeFullName != null)
                addImport(typeFullName);
            addParentInterface(parentInterface);
        }
    }

    protected ArrayList<TypeInfo> addParentInterfaces() {
        return null;
    }

    protected final void addParentInterface(TypeInfo type) {
        getContext().getItemInfo().addSuperInterface(type);
    }

    @Override
    protected final void doGenerate() {
        setChildAttributes();
        setParent();
        getContext().getItemInfo().generate();
    }

    private void setItemBasicInfo() {
        String name = getName();
        if (name == null || "".equals(name)) {
            throw new RuntimeException("生成器[" + this.getClass().getName() + "]没有设置类名");
        }
        getContext().getItemInfo().setTypeName(name);
        setAccessModifier();
    }

    private void setChildAttributes() {
        ArrayList<AnnotationInfo> attributeList = getAttributeList();
        if (attributeList == null) {
            attributeList = new ArrayList<AnnotationInfo>();
        }
        for (AnnotationInfo attr :
                attributeList) {
            String typeFullName = attr.getTypeInfo().getTypeFullName();
            if (typeFullName != null)
                addImport(typeFullName);
        }
        getContext().getItemInfo().setAttributes(attributeList);
    }

    protected abstract String getName();

    protected abstract void setAccessModifier();

    protected void setParent() {

    }

    protected ArrayList<AnnotationInfo> getAttributeList() {
        return null;
    }

    @Override
    protected void afterGenerate() {
        super.afterGenerate();

    }

    public final void addChildSyntax(BodyDeclaration childSyntax) {
        getContext().addChildSyntax(childSyntax);
    }
}
